home *** CD-ROM | disk | FTP | other *** search
/ MacHome 2000 March / MacHome CD (March 2000).iso / pc / Games / ACE! 1.7.2.sit / ACE! 1.7.2 / Development / Tutorial / Tutorial < prev    next >
Text File  |  1999-12-26  |  11KB  |  112 lines

  1. Introduction
  2.  
  3. This document is a tutorial - a guide to creating a module and modifying the module to use tabbed windows. The module "Death to the Ibby Squibbles" (hereafter referred to as the tutorial module) is complete and functional. You can place it in the "Modules" folder and use it to open the sample save games.
  4.  
  5. The tutorial module also demonstrates two features not commonly used in the modules provided with ACE - a tabbed window implemented with a tab control and radio buttons.
  6.  
  7. To follow the tutorial, you will need the applications "ResEdit", "HexEdit" and "ResCompare". Refer to the "Development (part I)" for information on obtaining these applications.
  8.  
  9.  
  10. Module Development
  11.  
  12. "Death to the Ibby Squibbles" is not a real game (to the best of my knowledge anyway). It is imagined to be a game of the 'shoot-em-up' genre that allows the player to save their progress in a save game file. From observing the game, we note that the information saved in the save game file must include the player's call-sign (name), whether or not the player has the 'Hyperbolic widgy woo' power-up, and their emergency setting (which can be either panic or whimper).
  13.  
  14. We create a save game file (called "save game") where the pilot's call-sign is "Space Dust", the pilot has the power-up, and the emergency setting is panic.
  15.  
  16. Using the Get File/Folder Info… command in ResEdit, we note that the save game file has no resource fork, and that the data fork is only 32 bytes long. We record the file type ('DISg') and creator ('DtIS') for later reference.
  17.  
  18. To create the tutorial module, I have used the "Module template" file. This file was duplicated and renamed as "Death to the Ibby Squibbles". The module was then opened with ResEdit, and the following changes were made:
  19.  
  20. • The 'vers' id 1 resource was updated.
  21. • The 'STR#" id 128 resource was modified.
  22. • The 'ACEm' resource's fields were modified.
  23.  
  24. Next, the module dialog was created. The 'DITL' id 128 resource was opened, and four controls were added: A edit text box (dialog id 1, for the pilot's call-sign), a checkbox (id 2, for the power-up) and two radio-buttons (id 3 and 4, for the emergency settings). Two static text items were also added.
  25.  
  26. Because this dialog is suitable for use on appearance manager systems (it contains no group boxes or lists), we delete the DITL id 129 and the DLOG id 129, and we change the id of the 'dlgx' resource from 129 to 128.
  27.  
  28. We open the data fork of the file using HexEdit:
  29.  
  30.  
  31.     Length:     20h    Type: DISg   Creator: DtIS       Fork: data
  32.   ___________________________________________________________________________
  33.   000000: 53 70 61 65 20 44 75 73 73 74 00 00 00 00 00 00    Space Dust......
  34.   000010: 03 84 01 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
  35.  
  36.  
  37. Our pilot's call-sign is "Space Dust", and we can see that this string is present in the data fork. Since the very first byte of the file contains the letter 'S', this string cannot be a Pascal style string. The presence of a zero immediately following the string confirms that this string is a C style string. There are 6 zero bytes following the last letter of the string, then a byte whose value is 03. Since this 03 cannot be part of a string (it's not a printable character), this suggests that the maximum length of the string is 15 printable characters (or 16 bytes including the zero terminator). As a double check, we can try to create a pilot in the game whose call-sign is longer than 15 characters. We also note that the game does not allow a pilot with no name.
  38.  
  39. The first 'ACEc' control (resource id 128) can now be created. It is named "Call-sign" (via the Get Resource Info command) and the fields of the resource are as follows:
  40.  
  41. Minimum: 1          (the minimum length of the call-sign is 1 character)
  42. Maximum: 15         (the maximum length of the call-sign is 15 characters)
  43. Offset 1, Offset 2: $00000000   (written to only one location, at offset 0)
  44. Link 1, Link 2: 0   (the control in the dialog will not be a radio button)
  45. Type: 1             (a C string)
  46. Equation to screen, Equation to file: 0   (no equation is used)
  47.  
  48. To determine the values and locations of the other game variables, we use save game comparison, since the save game data does not contain any time dependant elements (confirmed by making two save games, one a few seconds further into the game than the other, and comparing them with ResCompare).
  49.  
  50. We play the game with the previous save game file until we loose the power-up. We then save the game under a new filename ("save game 2"). Using ResCompare to compare the two files, we see that the value of the bytes at offset $10 and $11 have changed. In "save game", the value of these bytes were 3 and $84, in "save game 2" it is 0. We deduce that a short (two byte) variable starting at offset $10 determines if the pilot has the power-up, and that it's value is $0384 if the power-up is present, or 0 if it is not.
  51.  
  52. The second 'ACEc' resource (id 129) can now be created. It is named "Hyperbolic widgy woo" and the fields are:
  53.  
  54. Minimum: 0          (the value taken if the power-up is not present)
  55. Maximum: 900        (= $384, the value taken if the power-up is present)
  56. Offset 1, Offset 2: $00000010   (written to one location, starting at offset $10)
  57. Link 1, Link 2: 0   (the control in the dialog will not be a radio button)
  58. Type: 3             (an unsigned short)
  59. Equation to screen, Equation to file: 0   (no equation is used)
  60.  
  61. Finally, we use the same comparason method to determine the last game variable - the emergency setting. Playing the game from the first save game (not "save game 2") we change the emergency setting to 'whimper', and save the game under a new filename ("save game 3"). Using ResCompare again reveals that the only difference is the value of the byte at offset $12. It's value is 0 if the emergency setting is 'whimper', and 1 if it is 'panic'.
  62.  
  63. Because the emergency setting is implemented as a pair of radio buttons, we must create two 'ACEc' resources (id 130 and 131), one for each radio button. The 'ACEc' resources are named "whimper" and "panic". The fields for each resource are the same, and they are:
  64.  
  65. Minimum: 0   (the value taken if the emergency setting is 'whimper')
  66. Maximum: 1   (the value taken if the emergency setting is 'panic')
  67. Offset 1, Offset 2: $00000012   (written to one location, at offset $12)
  68. Link 1: 3    (the control number of the first radio button, the 3rd 'ACEc' resource)
  69. Link 2: 4    (the control number of the last radio button, the 4th 'ACEc' resource)
  70. Type: 7      (a byte)
  71. Equation to screen, Equation to file: 0   (no equation is used)
  72.  
  73. The module is now complete.
  74.  
  75.  
  76. Tabbed Window Development
  77.  
  78. The first step in modifying a module to use a tabbed window is to decide how many panes there will be in the dialogs, and what controls will appear in each dialog pane. For the tutorial module, we will have two panes, the first containing the call-sign and power-up controls, the second containing the emergency settings radio-buttons. The name of the first pane will be "Pilot" (since the first pane is concerned with pilot data) and the second pane will be called "Emergency".
  79.  
  80. We create a 'tab#' resource (id 128). The 'tab#' resource has two Tab info records, with Tab names "Pilot" and "Emergency" respectively.
  81.  
  82. Next, we create the two dialog panes by making two duplicates of the DITL id 128 resource, changing their ID to 200 and 201 and their names to "Pilot" and "Emergency" respectively. We open the 'DITL' id 200 and delete dialog items 3, 4 and 6. This leaves only the items that will appear in the first dialog pane. We position these remaining items so that the top left items are at left 10, top 45.
  83.  
  84. We open the 'DITL' id 201 and delete items 1, 2 and 5, leaving only the items that will appear in the second dialog pane. Again, we position the remaining items so that the top left item is at left 10, top 45.
  85.  
  86. Note that in this example, it was not necessary to renumber the remaining dialog items after deleting some dialog items - they just happened to automatically renumber correctly. Be aware that you might want to renumber items.
  87.  
  88. Next we must create the root dialogs (which will 'hold' the dialog panes). There is one root dialog for non-appearance manager systems, and one for appearance manager systems. The root dialogs require a corresponding 'DLOG' resource, so we create a 'DLOG' id 130 and id 131, making sure that the 'DITL' ID field is correctly set to 130 and 131 respectively. The other fields of the dialog are identical to 'DLOG' id 128 (for 'DLOG' id 130) or a 'DLOG' id 129 (for 'DLOG' id 131).
  89.  
  90. We now create the 'DITL' id 130 and 'DITL' id 131 dialogs as new (empty) dialogs. In the 'DITL' id 130, we put a user item at left 0, top 10, and we give it a height of 20 and ensure that it is enabled. The width of the user item, and the height and width of the dialog is initially unknown. We can make the dialog quite large and reduce it's size later.
  91.  
  92. Before editing the 'DITL' id 131, we create a pop-up group box control ('CNTL' id 3000). The fields of this resource are as follows:
  93.  
  94. Value: 128    (the id of the 'tab#' resource)
  95. Visible: True
  96. Max: 0
  97. Min: 0
  98. ProcID: 128   (the procedure id of a pop-up group box control)
  99. RefCon: 0
  100. Title:        (no title)
  101.  
  102. The BoundsRect fields are initially unknown, as we do not know what size the dialog should be. We can set these to a reasonable value (say 0, 0, 200, 300) and adjust them later.
  103.  
  104. We can now put a control in DITL id 131. This control has a resource id of 1000, and it is positioned at left -1, top 10. The control should be enabled.
  105.  
  106. The tabbed window is now complete.
  107.  
  108. Finally, a 'ACEi' resource must be created for the tabbed windows. This is necessary to ensure that the 'ACEc' resources are correctly mapped to their corresponding dialog items. We need an 'ACEi' resource for each root dialog, with a corresponding id (i.e. id 130 and 131).
  109.  
  110. Since the two root dialogs consist of the same number of items, and since we use the same dialog panes for both the root dialogs, the fields of the 'ACEi' resources will be identical. So we can create an 'ACEi' resource id 130, fill out the fields, and then duplicate it (remembering to change the id of the duplicate to 131).
  111.  
  112. There number of controls in the 'ACEi' resource is 4 (the same as the number of 'ACEc' resources). The fields consist of the 'total' dialog item id that corresponds to that control. The total dialog items id's are calculated as follows: Add the number of items in the root dialog (1) to each control in the first pane - these are the 'total' dialog item id's for the controls in the first dialog pane. In this case, 1 + 1 = 2 and 1 + 2 = 3. For the next dialog pane, add as before but include the number of items in the first dialog pane (3). So the two radio buttons have a 'total' dialog item id of 1 + 3 + 1 = 5 and 1 + 3 + 2 = 6.